package com.wetao.lib_common.utils;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.Log;

import com.orhanobut.logger.Logger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;


/**
 * Created by ${GuoZhaoHui} on 2017/11/27.
 * Email:guozhaohui628@gmail.com
 */

public class WifiSupport {
    /** 定义几种加密方式，一种是WEP，一种是WPA/WPA2，还有没有密码的情况 */
    public enum WifiCipherType {
        WIFI_CIPHER_WEP, WIFI_CIPHER_WPA_EAP, WIFI_CIPHER_WPA_PSK, WIFI_CIPHER_WPA2_PSK, WIFI_CIPHER_NOPASS, WIFICIPHER_INVALID
    }
    private WifiManager wifiManager;
    private WifiBroadCastReceiver mReceiver;


    /** 定义几种加密方式，一种是WEP，一种是WPA/WPA2，还有没有密码的情况 */



    public WifiSupport(Context context) {
        wifiManager = (WifiManager) context
                .getSystemService(Service.WIFI_SERVICE);
    }

    private static final String TAG = "WifiSupport";


    private wifiListener mWifiListener;
    public interface wifiListener {
        //已关闭
        void disabled();
        //正在关闭
        void disabling();
        //已启用
        void enabled();
        //启动中
        void enabling();
        //未知
        void unknown();
        //连接到wifi
        void wifi_connected(String wifi_name);
        //断开
        void wifi_disconnect();
        //密码错误
        void wifi_pwd_error();

        //WiFi列表改变
        void wifi_list(List<ScanResult> wifiList1);
    }
    public void setWifiListener(wifiListener wifiListener){
        this.mWifiListener= wifiListener;
    }




    /*---------------------------------------WIFI状态监听-------------------------------------------------------*/

    class WifiBroadCastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
            switch (wifiState) {
                case WifiManager.WIFI_STATE_DISABLED://WIFI已关闭
                    mWifiListener.disabled();
                     Logger.i("onReceive: WIFI已关闭");
                    break;
                case WifiManager.WIFI_STATE_DISABLING://WIFI正在关闭中
                    mWifiListener.disabling();
                     Logger.i(TAG, "onReceive: WIFI正在关闭中");
                    break;
                case WifiManager.WIFI_STATE_ENABLED://WIFI已启用
                    mWifiListener.enabled();
                     Logger.i("onReceive: WIFI已启用");
                    break;
                case WifiManager.WIFI_STATE_ENABLING://WIFI正在启动中
                    mWifiListener.enabling();
                    Logger.i( "onReceive: WIFI正在启动中");
                    break;
                case WifiManager.WIFI_STATE_UNKNOWN://未知WIFI状态
                    mWifiListener.unknown();
                     Logger.i( "onReceive: 未知WIFI状态");
                    break;
            }

            if (intent.getAction().equals(WifiManager.RSSI_CHANGED_ACTION)) {
                Logger.i( "wifi信号强度变化");
            }


            if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                Log.i(TAG, "wifi列表变化");
                List<ScanResult> wifiList1 = wifiManager.getScanResults();
                mWifiListener.wifi_list(wifiList1);

            }
            //wifi连接上与否
            if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {

                NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

                // 刷新状态显示

                if (NetworkInfo.State.DISCONNECTED == info.getState()) {//wifi没连接上
                    mWifiListener.wifi_disconnect();
                    System.out.println("wifi没有连接");
                } else if (NetworkInfo.State.CONNECTED == info.getState()) {//wifi连接上了

                    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                    //获取当前wifi名称
                    mWifiListener.wifi_connected(wifiInfo.getSSID());

                    System.out.println("wifi连接上了");


                } else if (NetworkInfo.State.CONNECTING == info.getState()) {//正在连接
                    Logger.d(TAG, "wifi正在连接");

                }


            }


            if (intent.getAction().equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
                int error = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR,
                        0);
                if (WifiManager.ERROR_AUTHENTICATING == error){
                    Log.d(TAG, "密码认证错误Code为：" + error);
                    //remove(wifiManager.getConnectionInfo().getNetworkId());
                    //Toast.makeText(context, "wifi密码认证错误！"+error, Toast.LENGTH_SHORT).show();
                    mWifiListener.wifi_pwd_error();
                }
            }


        }
    }



    /**
     * 忘记网络
     * @param networkId
     * @return .
     */
    public boolean remove(int networkId){
        if (null == wifiManager){
            Log.e(TAG,"WifiManager 没有初始化");
            return false;
        }
        boolean isRemoved = wifiManager.removeNetwork(networkId);

        if (!isRemoved) {
            int index = 0;
            while (!isRemoved && index < 10) {
                index ++;
                isRemoved =  wifiManager.removeNetwork(networkId);
            }
        }

        if (isRemoved) {
            wifiManager.saveConfiguration();
        }
        return isRemoved;
    }




    /**
     * 注册广播监听wifi状态
     */
    public void registerReceiver(Context context) {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); //wifi打开关闭
        //连接
        filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        //wifi 列表 wifi关闭情况下可以扫描WiFi
        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        //Wifi信号强度变化
        filter.addAction(WifiManager.RSSI_CHANGED_ACTION);
        mReceiver = new WifiBroadCastReceiver();
        context.registerReceiver(mReceiver, filter);
        Log.i(TAG, "registerReceiver: 注册广播");
    }



    /**
     * 注销广播
     */
    public void unregisterReceiver(Context context) {
        if (mReceiver != null) {
            context.unregisterReceiver(mReceiver);
            mReceiver = null;
        }
        Log.i(TAG, "unregisterReceiver: 注销广播");
    }





    public  List<ScanResult> getWifiScanResult() {

        return wifiManager.getScanResults();
    }



    public  boolean isWifiEnable(Context context) {
        return wifiManager.isWifiEnabled();
    }

    public  WifiInfo getConnectedWifiInfo(Context context) {
        return wifiManager.getConnectionInfo();
    }

    public  List getConfigurations(Context context) {
        return wifiManager.getConfiguredNetworks();
    }


    public static WifiConfiguration createWifiConfig(String SSID, String password, WifiCipherType type) {

        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + SSID + "\"";

        if (type == WifiCipherType.WIFI_CIPHER_NOPASS) {
//            config.wepKeys[0] = "";  //注意这里
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
//            config.wepTxKeyIndex = 0;
        }

        if (type == WifiCipherType.WIFI_CIPHER_WEP) {
            config.preSharedKey = "\"" + password + "\"";
            config.hiddenSSID = true;
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        }

        if (type == WifiCipherType.WIFI_CIPHER_WPA_PSK) {
            config.preSharedKey = "\"" + password + "\"";
            config.hiddenSSID = true;
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            config.status = WifiConfiguration.Status.ENABLED;

        }

        return config;

    }





    public int CreateWifiInfo2(ScanResult wifiinfo, String pwd) {



        WifiCipherType type;

        if (wifiinfo.capabilities.contains("WPA2-PSK")) {
            // WPA-PSK加密
            type = WifiCipherType.WIFI_CIPHER_WPA2_PSK;
        } else if (wifiinfo.capabilities.contains("WPA-PSK")) {
            // WPA-PSK加密
            type = WifiCipherType.WIFI_CIPHER_WPA_PSK;
        } else if (wifiinfo.capabilities.contains("WPA-EAP")) {
            // WPA-EAP加密
            type = WifiCipherType.WIFI_CIPHER_WPA_EAP;
        } else if (wifiinfo.capabilities.contains("WEP")) {
            // WEP加密
            type = WifiCipherType.WIFI_CIPHER_WEP;
        } else {
            // 无密码
            type = WifiCipherType.WIFI_CIPHER_NOPASS;
        }

        WifiConfiguration config = CreateWifiInfo(wifiinfo.SSID,
                wifiinfo.BSSID, pwd, type);
        if (config != null) {
            return wifiManager.addNetwork(config);
        } else {
            return -1;
        }
    }





    /**
     * 接入某个wifi热点
     */
    public  boolean addNetWork(WifiConfiguration config) {


        WifiInfo wifiinfo = wifiManager.getConnectionInfo();

        if (null != wifiinfo) {
            wifiManager.disableNetwork(wifiinfo.getNetworkId());
        }

        boolean result = false;

        if (config.networkId > 0) {
            result = wifiManager.enableNetwork(config.networkId, true);
            wifiManager.updateNetwork(config);
        } else {

            int i = wifiManager.addNetwork(config);
            result = false;

            if (i > 0) {

                wifiManager.saveConfiguration();
                return wifiManager.enableNetwork(i, true);
            }
        }

        return result;

    }

    /**
     * 判断wifi热点支持的加密方式
     */
    public  WifiCipherType getWifiCipher(String s) {

        if (s.isEmpty()) {
            return WifiCipherType.WIFICIPHER_INVALID;
        } else if (s.contains("WEP")) {
            return WifiCipherType.WIFI_CIPHER_WEP;
        } else if (s.contains("WPA") || s.contains("WPA2") || s.contains("WPS")) {
            return WifiCipherType.WIFI_CIPHER_WPA_PSK;
        } else {
            return WifiCipherType.WIFI_CIPHER_NOPASS;
        }
    }

    //查看以前是否也配置过这个网络
    public  WifiConfiguration isExsits(String SSID) {


        List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
        for (WifiConfiguration existingConfig : existingConfigs) {
            if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
                return existingConfig;
            }
        }
        return null;
    }

    public  static WifiConfiguration isExsits(String SSID,Context context) {
        WifiManager wifiManager = (WifiManager) context
                .getSystemService(Service.WIFI_SERVICE);

        List<WifiConfiguration> existingConfigs = wifiManager.getConfiguredNetworks();
        if(existingConfigs!=null&&existingConfigs.size()>0){
            for (WifiConfiguration existingConfig : existingConfigs) {
                if(!StringUtil.isEmpty(existingConfig.SSID)){
                    if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
                        return existingConfig;
                    }
                }

            }
        }

        return null;
    }

    // 打开WIFI
    public  void openWifi(Context context) {

        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
            Logger.i("-----2");
        }
    }


    //重连到接入点，即使已经连接上了

    public void reassociate(){

        if (wifiManager!=null) {
            wifiManager.reassociate();
        }
    }




    //如果现在没有连接的话，则重连接

    public void reconnect(){

        if (wifiManager!=null) {
            wifiManager.reconnect();
        }
    }


    //更新一个网络连接信息

    public void updateNetwork(WifiConfiguration config){

        if (wifiManager!=null&&wifiManager.isWifiEnabled()) {
            wifiManager.updateNetwork(config);
        }
    }


    // 关闭WIFI
    public  void closeWifi(Context context) {

        if (wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(false);
        }
    }

    public static boolean isOpenWifi(Context context){
        WifiManager wifimanager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        boolean b = wifimanager.isWifiEnabled();
        return b;
    }



    /** 配置一个连接 */
    public WifiConfiguration CreateWifiInfo(String SSID, String BSSID,
                                            String password, WifiCipherType type) {

        int priority;

        WifiConfiguration config = this.isExsits(SSID);
        if (config != null) {
            // 本机之前配置过此wifi热点，调整优先级后，直接返回
            return setMaxPriority(config);
        }

        config = new WifiConfiguration();
        /* 清除之前的连接信息 */
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + SSID + "\"";
        config.status = WifiConfiguration.Status.ENABLED;

        priority = getMaxPriority() + 1;
        if (priority > 99999) {
            priority = shiftPriorityAndSave();
        }

        config.priority = priority; // 2147483647;
        /* 各种加密方式判断 */
        if (type == WifiCipherType.WIFI_CIPHER_NOPASS) {
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        } else if (type == WifiCipherType.WIFI_CIPHER_WEP) {
            config.preSharedKey = "\"" + password + "\"";

            config.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.SHARED);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            config.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.WEP104);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        } else if (type == WifiCipherType.WIFI_CIPHER_WPA_EAP) {

            config.preSharedKey = "\"" + password + "\"";
            config.hiddenSSID = true;
            config.status = WifiConfiguration.Status.ENABLED;
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);

            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.CCMP);
            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN
                    | WifiConfiguration.Protocol.WPA);

        } else if (type == WifiCipherType.WIFI_CIPHER_WPA_PSK) {

            config.preSharedKey = "\"" + password + "\"";
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.CCMP);
            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN
                    | WifiConfiguration.Protocol.WPA);

        } else if (type == WifiCipherType.WIFI_CIPHER_WPA2_PSK) {

            config.preSharedKey = "\"" + password + "\"";
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.CCMP);
            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

        } else {
            return null;
        }

        return config;
    }




    public WifiConfiguration setMaxPriority(WifiConfiguration config) {
        int priority = getMaxPriority() + 1;
        if (priority > 99999) {
            priority = shiftPriorityAndSave();
        }

        config.priority = priority;
        wifiManager.updateNetwork(config);

        // 本机之前配置过此wifi热点，直接返回
        return config;
    }

    public boolean ConnectToNetID(int netID) {
        return wifiManager.enableNetwork(netID, true);
    }

    private int getMaxPriority() {
        List<WifiConfiguration> localList = this.wifiManager
                .getConfiguredNetworks();
        int i = 0;
        Iterator<WifiConfiguration> localIterator = localList.iterator();
        while (true) {
            if (!localIterator.hasNext())
                return i;
            WifiConfiguration localWifiConfiguration = (WifiConfiguration) localIterator
                    .next();
            if (localWifiConfiguration.priority <= i)
                continue;
            i = localWifiConfiguration.priority;
        }
    }


    private int shiftPriorityAndSave() {
        List<WifiConfiguration> localList = this.wifiManager
                .getConfiguredNetworks();
        sortByPriority(localList);
        int i = localList.size();
        for (int j = 0;; ++j) {
            if (j >= i) {
                this.wifiManager.saveConfiguration();
                return i;
            }
            WifiConfiguration localWifiConfiguration = (WifiConfiguration) localList
                    .get(j);
            localWifiConfiguration.priority = j;
            this.wifiManager.updateNetwork(localWifiConfiguration);
        }
    }
    private void sortByPriority(List<WifiConfiguration> paramList) {
        Collections.sort(paramList, new SjrsWifiManagerCompare());
    }

    class SjrsWifiManagerCompare implements Comparator<WifiConfiguration> {
        public int compare(WifiConfiguration paramWifiConfiguration1,
                           WifiConfiguration paramWifiConfiguration2) {
            return paramWifiConfiguration1.priority
                    - paramWifiConfiguration2.priority;
        }
    }



    /**
     * 将idAddress转化成string类型的Id字符串
     *
     * @param idString
     * @return
     */
    public static String getStringId(int idString) {
        StringBuffer sb = new StringBuffer();
        int b = (idString >> 0) & 0xff;
        sb.append(b + ".");
        b = (idString >> 8) & 0xff;
        sb.append(b + ".");
        b = (idString >> 16) & 0xff;
        sb.append(b + ".");
        b = (idString >> 24) & 0xff;
        sb.append(b);
        return sb.toString();
    }

    /**
     * 设置安全性
     *
     * @param capabilities
     * @return
     */
    public static String getCapabilitiesString(String capabilities) {
        if (capabilities.contains("WEP")) {
            return "WEP";
        } else if (capabilities.contains("WPA") || capabilities.contains("WPA2") || capabilities.contains("WPS")) {
            return "WPA/WPA2";
        } else {
            return "OPEN";
        }
    }

    public static boolean getIsWifiEnabled(Context context) {
        WifiManager wifimanager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        return wifimanager.isWifiEnabled();
    }

    /**
     * 去除同名WIFI
     *
     * @param oldSr 需要去除同名的列表
     * @return 返回不包含同命的列表
     */
    public static List<ScanResult> noSameName(List<ScanResult> oldSr)
    {
        List<ScanResult> newSr = new ArrayList<ScanResult>();
        for (ScanResult result : oldSr)
        {
            if (!TextUtils.isEmpty(result.SSID) && !containName(newSr, result.SSID))
                newSr.add(result);
        }
        return newSr;
    }
    /**
     * 判断一个扫描结果中，是否包含了某个名称的WIFI
     * @param sr 扫描结果
     * @param name 要查询的名称
     * @return 返回true表示包含了该名称的WIFI，返回false表示不包含
     */
    public static boolean containName(List<ScanResult> sr, String name)
    {
        for (ScanResult result : sr)
        {
            if (!TextUtils.isEmpty(result.SSID) && result.SSID.equals(name))
                return true;
        }
        return false;
    }

    /**
     * 返回level 等级
     */
    public static int getLevel(int level){
        if (Math.abs(level) < 50) {
            return 4;
        } else if (Math.abs(level) < 60) {
            return 3;
        } else if (Math.abs(level) < 70) {
            return 2;
        } else if (Math.abs(level) < 85) {
        return 1;
        } else {
            return 0;
        }
    }

}
